package utils;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * 根据传入的Config对象创建连接池获得链接
 * @author zhrb
 */
public class DbUtil {
    
    private static final Logger logger = LogManager.getLogger(DbUtil.class);
    
    private static ConcurrentHashMap<Config,ComboPooledDataSource> dataSourceMap = new ConcurrentHashMap<>();
    
    /**
     * 根据config获取相应的connection，如果dataSource已经存在则直接使用。
     * @param config
     * @return
     * @throws Exception
     */
    public  static Connection getConnection(Config config) throws SQLException,PropertyVetoException {
        ComboPooledDataSource dataSource = dataSourceMap.get(config);
        try {
            if(dataSource==null){
                dataSource = new ComboPooledDataSource();
                dataSource.setDriverClass(config.getDriverClassName());
                dataSource.setJdbcUrl(config.getUrl());
                dataSource.setUser(config.getUserName());
                dataSource.setPassword(config.getPassword());
                dataSource.setInitialPoolSize(5);
                dataSource.setMinPoolSize(5);
                dataSource.setMaxPoolSize(10);
                // 以下两句用于设置自动重连
                dataSource.setIdleConnectionTestPeriod(10);
                dataSource.setTestConnectionOnCheckin(true);
                dataSourceMap.put(config, dataSource);
            }
            return dataSource.getConnection();
        } catch (SQLException e) {
            logger.error("getting the connection, e ="+e);
            throw e;
        } catch (PropertyVetoException e) {
            logger.error("setting the DriverClass, e"+e);
            throw e;
        }
        
    }

    //jdk1.7的AutoCloseable语法
    /**
     * 如需同时关闭resultset, statement与connection, 请依次按顺序关闭，即按照r->s->c的顺序将参数放入closeAll
     * @param obj
     */
    public static void closeAll(AutoCloseable... obj) {
            for (AutoCloseable item : obj) {
                try {
                    if(item!=null){
                        item.close();
                    }
                } catch (Exception e) {
                        logger.error("closing the resultSet, statement, connection,e:"+e);
                }
            }
    }
}
